/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.jpa.controllers;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import co.com.entities.Asteroide;
import java.util.ArrayList;
import java.util.List;
import co.com.entities.ClasificacionAsteroide;
import co.com.entities.Unidaddistancia;
import co.com.jpa.controllers.exceptions.NonexistentEntityException;
import co.com.jpa.controllers.exceptions.PreexistingEntityException;
import java.math.BigDecimal;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author dloaiza
 */
public class UnidaddistanciaJpaController implements Serializable {

    public UnidaddistanciaJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Unidaddistancia unidaddistancia) throws PreexistingEntityException, Exception {
        if (unidaddistancia.getAsteroideList() == null) {
            unidaddistancia.setAsteroideList(new ArrayList<Asteroide>());
        }
        if (unidaddistancia.getClasificacionAsteroideList() == null) {
            unidaddistancia.setClasificacionAsteroideList(new ArrayList<ClasificacionAsteroide>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Asteroide> attachedAsteroideList = new ArrayList<Asteroide>();
            for (Asteroide asteroideListAsteroideToAttach : unidaddistancia.getAsteroideList()) {
                asteroideListAsteroideToAttach = em.getReference(asteroideListAsteroideToAttach.getClass(), asteroideListAsteroideToAttach.getNmidAsteroide());
                attachedAsteroideList.add(asteroideListAsteroideToAttach);
            }
            unidaddistancia.setAsteroideList(attachedAsteroideList);
            List<ClasificacionAsteroide> attachedClasificacionAsteroideList = new ArrayList<ClasificacionAsteroide>();
            for (ClasificacionAsteroide clasificacionAsteroideListClasificacionAsteroideToAttach : unidaddistancia.getClasificacionAsteroideList()) {
                clasificacionAsteroideListClasificacionAsteroideToAttach = em.getReference(clasificacionAsteroideListClasificacionAsteroideToAttach.getClass(), clasificacionAsteroideListClasificacionAsteroideToAttach.getNmidClasificacion());
                attachedClasificacionAsteroideList.add(clasificacionAsteroideListClasificacionAsteroideToAttach);
            }
            unidaddistancia.setClasificacionAsteroideList(attachedClasificacionAsteroideList);
            em.persist(unidaddistancia);
            for (Asteroide asteroideListAsteroide : unidaddistancia.getAsteroideList()) {
                Unidaddistancia oldUnidadMedidaOfAsteroideListAsteroide = asteroideListAsteroide.getUnidadMedida();
                asteroideListAsteroide.setUnidadMedida(unidaddistancia);
                asteroideListAsteroide = em.merge(asteroideListAsteroide);
                if (oldUnidadMedidaOfAsteroideListAsteroide != null) {
                    oldUnidadMedidaOfAsteroideListAsteroide.getAsteroideList().remove(asteroideListAsteroide);
                    oldUnidadMedidaOfAsteroideListAsteroide = em.merge(oldUnidadMedidaOfAsteroideListAsteroide);
                }
            }
            for (ClasificacionAsteroide clasificacionAsteroideListClasificacionAsteroide : unidaddistancia.getClasificacionAsteroideList()) {
                Unidaddistancia oldUnidadDistanciaOfClasificacionAsteroideListClasificacionAsteroide = clasificacionAsteroideListClasificacionAsteroide.getUnidadDistancia();
                clasificacionAsteroideListClasificacionAsteroide.setUnidadDistancia(unidaddistancia);
                clasificacionAsteroideListClasificacionAsteroide = em.merge(clasificacionAsteroideListClasificacionAsteroide);
                if (oldUnidadDistanciaOfClasificacionAsteroideListClasificacionAsteroide != null) {
                    oldUnidadDistanciaOfClasificacionAsteroideListClasificacionAsteroide.getClasificacionAsteroideList().remove(clasificacionAsteroideListClasificacionAsteroide);
                    oldUnidadDistanciaOfClasificacionAsteroideListClasificacionAsteroide = em.merge(oldUnidadDistanciaOfClasificacionAsteroideListClasificacionAsteroide);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findUnidaddistancia(unidaddistancia.getCdunidad()) != null) {
                throw new PreexistingEntityException("Unidaddistancia " + unidaddistancia + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Unidaddistancia unidaddistancia) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Unidaddistancia persistentUnidaddistancia = em.find(Unidaddistancia.class, unidaddistancia.getCdunidad());
            List<Asteroide> asteroideListOld = persistentUnidaddistancia.getAsteroideList();
            List<Asteroide> asteroideListNew = unidaddistancia.getAsteroideList();
            List<ClasificacionAsteroide> clasificacionAsteroideListOld = persistentUnidaddistancia.getClasificacionAsteroideList();
            List<ClasificacionAsteroide> clasificacionAsteroideListNew = unidaddistancia.getClasificacionAsteroideList();
            List<Asteroide> attachedAsteroideListNew = new ArrayList<Asteroide>();
            for (Asteroide asteroideListNewAsteroideToAttach : asteroideListNew) {
                asteroideListNewAsteroideToAttach = em.getReference(asteroideListNewAsteroideToAttach.getClass(), asteroideListNewAsteroideToAttach.getNmidAsteroide());
                attachedAsteroideListNew.add(asteroideListNewAsteroideToAttach);
            }
            asteroideListNew = attachedAsteroideListNew;
            unidaddistancia.setAsteroideList(asteroideListNew);
            List<ClasificacionAsteroide> attachedClasificacionAsteroideListNew = new ArrayList<ClasificacionAsteroide>();
            for (ClasificacionAsteroide clasificacionAsteroideListNewClasificacionAsteroideToAttach : clasificacionAsteroideListNew) {
                clasificacionAsteroideListNewClasificacionAsteroideToAttach = em.getReference(clasificacionAsteroideListNewClasificacionAsteroideToAttach.getClass(), clasificacionAsteroideListNewClasificacionAsteroideToAttach.getNmidClasificacion());
                attachedClasificacionAsteroideListNew.add(clasificacionAsteroideListNewClasificacionAsteroideToAttach);
            }
            clasificacionAsteroideListNew = attachedClasificacionAsteroideListNew;
            unidaddistancia.setClasificacionAsteroideList(clasificacionAsteroideListNew);
            unidaddistancia = em.merge(unidaddistancia);
            for (Asteroide asteroideListOldAsteroide : asteroideListOld) {
                if (!asteroideListNew.contains(asteroideListOldAsteroide)) {
                    asteroideListOldAsteroide.setUnidadMedida(null);
                    asteroideListOldAsteroide = em.merge(asteroideListOldAsteroide);
                }
            }
            for (Asteroide asteroideListNewAsteroide : asteroideListNew) {
                if (!asteroideListOld.contains(asteroideListNewAsteroide)) {
                    Unidaddistancia oldUnidadMedidaOfAsteroideListNewAsteroide = asteroideListNewAsteroide.getUnidadMedida();
                    asteroideListNewAsteroide.setUnidadMedida(unidaddistancia);
                    asteroideListNewAsteroide = em.merge(asteroideListNewAsteroide);
                    if (oldUnidadMedidaOfAsteroideListNewAsteroide != null && !oldUnidadMedidaOfAsteroideListNewAsteroide.equals(unidaddistancia)) {
                        oldUnidadMedidaOfAsteroideListNewAsteroide.getAsteroideList().remove(asteroideListNewAsteroide);
                        oldUnidadMedidaOfAsteroideListNewAsteroide = em.merge(oldUnidadMedidaOfAsteroideListNewAsteroide);
                    }
                }
            }
            for (ClasificacionAsteroide clasificacionAsteroideListOldClasificacionAsteroide : clasificacionAsteroideListOld) {
                if (!clasificacionAsteroideListNew.contains(clasificacionAsteroideListOldClasificacionAsteroide)) {
                    clasificacionAsteroideListOldClasificacionAsteroide.setUnidadDistancia(null);
                    clasificacionAsteroideListOldClasificacionAsteroide = em.merge(clasificacionAsteroideListOldClasificacionAsteroide);
                }
            }
            for (ClasificacionAsteroide clasificacionAsteroideListNewClasificacionAsteroide : clasificacionAsteroideListNew) {
                if (!clasificacionAsteroideListOld.contains(clasificacionAsteroideListNewClasificacionAsteroide)) {
                    Unidaddistancia oldUnidadDistanciaOfClasificacionAsteroideListNewClasificacionAsteroide = clasificacionAsteroideListNewClasificacionAsteroide.getUnidadDistancia();
                    clasificacionAsteroideListNewClasificacionAsteroide.setUnidadDistancia(unidaddistancia);
                    clasificacionAsteroideListNewClasificacionAsteroide = em.merge(clasificacionAsteroideListNewClasificacionAsteroide);
                    if (oldUnidadDistanciaOfClasificacionAsteroideListNewClasificacionAsteroide != null && !oldUnidadDistanciaOfClasificacionAsteroideListNewClasificacionAsteroide.equals(unidaddistancia)) {
                        oldUnidadDistanciaOfClasificacionAsteroideListNewClasificacionAsteroide.getClasificacionAsteroideList().remove(clasificacionAsteroideListNewClasificacionAsteroide);
                        oldUnidadDistanciaOfClasificacionAsteroideListNewClasificacionAsteroide = em.merge(oldUnidadDistanciaOfClasificacionAsteroideListNewClasificacionAsteroide);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                BigDecimal id = unidaddistancia.getCdunidad();
                if (findUnidaddistancia(id) == null) {
                    throw new NonexistentEntityException("The unidaddistancia with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(BigDecimal id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Unidaddistancia unidaddistancia;
            try {
                unidaddistancia = em.getReference(Unidaddistancia.class, id);
                unidaddistancia.getCdunidad();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The unidaddistancia with id " + id + " no longer exists.", enfe);
            }
            List<Asteroide> asteroideList = unidaddistancia.getAsteroideList();
            for (Asteroide asteroideListAsteroide : asteroideList) {
                asteroideListAsteroide.setUnidadMedida(null);
                asteroideListAsteroide = em.merge(asteroideListAsteroide);
            }
            List<ClasificacionAsteroide> clasificacionAsteroideList = unidaddistancia.getClasificacionAsteroideList();
            for (ClasificacionAsteroide clasificacionAsteroideListClasificacionAsteroide : clasificacionAsteroideList) {
                clasificacionAsteroideListClasificacionAsteroide.setUnidadDistancia(null);
                clasificacionAsteroideListClasificacionAsteroide = em.merge(clasificacionAsteroideListClasificacionAsteroide);
            }
            em.remove(unidaddistancia);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Unidaddistancia> findUnidaddistanciaEntities() {
        return findUnidaddistanciaEntities(true, -1, -1);
    }

    public List<Unidaddistancia> findUnidaddistanciaEntities(int maxResults, int firstResult) {
        return findUnidaddistanciaEntities(false, maxResults, firstResult);
    }

    private List<Unidaddistancia> findUnidaddistanciaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Unidaddistancia.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Unidaddistancia findUnidaddistancia(BigDecimal id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Unidaddistancia.class, id);
        } finally {
            em.close();
        }
    }

    public int getUnidaddistanciaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Unidaddistancia> rt = cq.from(Unidaddistancia.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
